package com.wxmit.framework.satoken.core.util;


import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.temp.SaTempUtil;
import cn.hutool.core.lang.Assert;
import com.wxmit.system.domain.LoginUser;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Objects;

/**
 * @Description 封装 StpUtil ，丰富应用场景，实现多系统账户认证的问题
 * @Author huangxiong
 * @Date 2022/7/11 09:05
 * @Version V1.0
 */
@Slf4j
public class StpUserUtil  {

    public static final String LOGIN_USER_NAME = "loginUser";

    public static final String DEF_USER_TYPE = "sysUser";

    public static final String SALT = "wxmit";

    public static void resetAdminLogic(){
        StpLogic adminUserStpLogic = new StpLogic(DEF_USER_TYPE);
        StpUtil.setStpLogic(adminUserStpLogic);
    }

    public static String loginWithLoginUser(LoginUser loginUser){
        resetAdminLogic();
        StpUtil.login(loginUser.getId());
        setLoginUser(loginUser);
        return StpUtil.getTokenValue();
    }

    public static void setLoginUser(LoginUser loginUser){
        StpUtil.getSession().set(LOGIN_USER_NAME,loginUser);
        StpUtil.getTokenSession().set(LOGIN_USER_NAME,loginUser);
    }


    public static LoginUser getLoginUser() {
        if(!StpUtil.isLogin()){
          throw new NotLoginException(NotLoginException.DEFAULT_MESSAGE,DEF_USER_TYPE,NotLoginException.NOT_TOKEN);
        }
        LoginUser loginUser = (LoginUser) StpUtil.getSession().get(LOGIN_USER_NAME);
        if(Objects.isNull(loginUser)){
            loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_NAME);
            StpUtil.getSession().set(LOGIN_USER_NAME,loginUser);
        }
        return loginUser;
    }

    public static <T> T getUser(Class<T> clazz){
        if(!StpUtil.isLogin()){
            throw new NotLoginException(NotLoginException.DEFAULT_MESSAGE,DEF_USER_TYPE,NotLoginException.NOT_TOKEN);
        }
        return  (T)getLoginUser().getUserObj();
    }
    public static Long getUserId(){
        return StpUtil.getLoginIdAsLong();
    }

    public static Long obj2Id(Object id){
        Assert.notNull(id,"id 不能为空！");
        return (Long) id;
    }

    public static Boolean isAdmin() {
        return  isAdmin(StpUtil.getLoginId(-1L));
    }

    public static String encryptionPw(String pw){
        return SaSecureUtil.md5BySalt(pw, SALT);
    }

    public static Boolean eqPassword(String pw,String loginPw){
        return Objects.equals(pw,encryptionPw(loginPw));
    }

    public static List<String> getPermissionList() {
        return StpUtil.getPermissionList();
    }

    public static void logout() {
        LoginUser loginUser = getLoginUser();
        if(Objects.nonNull(loginUser.getRefreshToken())){
            SaTempUtil.deleteToken(loginUser.getRefreshToken());
        }
        StpUtil.logout();

    }

    public static void kickout(Object id) {
        String tokenValue = StpUtil.getTokenValueByLoginId(id);
        if(Objects.isNull(tokenValue)){
            // 没有token则表示并无登录用户
            return;
        }
        SaSession saSession = StpUtil.getTokenSessionByToken(tokenValue);
        LoginUser loginUser = (LoginUser) saSession.get(LOGIN_USER_NAME);
        String refreshToken = loginUser.getRefreshToken();
        SaTempUtil.deleteToken(refreshToken);
        StpUtil.kickout(id);
    }


    public static Object getLoginId() {
        return StpUtil.getLoginId();
    }

    public static Boolean isAdmin(Long userId) {
        return userId == 1L;
    }
}
